//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.demo.service;

import com.example.demo.entity.Order;
import com.example.demo.entity.OrderVersion;
import com.example.demo.repository.OrderRepository;
import com.example.demo.repository.OrderVersionRepository;
import com.example.demo.util.HashUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.SortedMap;
import lombok.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {
    @Autowired
    private final OrderRepository orderRepository;
    @Autowired
    private final OrderVersionRepository versionRepository;
    @Autowired
    private final HashUtils hashUtils;
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
    
    // 修改: 添加对 IdService 的可选注入处理
    @Autowired(required = false)
    private IdService idService;

    @Transactional
    public Order createOrder(Order order) {
        order.setCreatedAt(LocalDateTime.now());
        order.setCurrentVersion(1L);
        String initialHash = this.hashUtils.calculateInitialHash(order.getCoreFields());
        order.setCurrentHash(initialHash);
        Order savedOrder = (Order)this.orderRepository.save(order);
        OrderVersion lastGlobal = this.versionRepository.findLast();
        OrderVersion firstVersion = new OrderVersion();
        firstVersion.setOrder(savedOrder);
        firstVersion.setVersion(1L);
        firstVersion.setDataSnapshot(this.getCoreFieldsJson(order));
        firstVersion.setCurrentHash(initialHash);
        firstVersion.setGlobalPreviousHash((String)null);
        if (lastGlobal != null) {
            firstVersion.setGlobalPreviousHash(lastGlobal.getGlobalCurrentHash());
            firstVersion.setGlobalPreviousVersion(lastGlobal);
            String newGlobalHash = this.hashUtils.calculateChainHash(lastGlobal.getGlobalCurrentHash(), savedOrder.getCoreFields());
            firstVersion.setGlobalCurrentHash(newGlobalHash);
        } else {
            firstVersion.setGlobalCurrentHash(this.hashUtils.calculateInitialHash(savedOrder.getCoreFields()));
        }

        firstVersion.setPreviousHash((String)null);
        firstVersion.setUpdateTimestamp(LocalDateTime.now());
        this.versionRepository.save(firstVersion);
        return savedOrder;
    }

    @Transactional
    public Order updateOrder(Long orderId, Order updatedOrder) {
        Order existingOrder = (Order)this.orderRepository.findById(orderId).orElseThrow(() -> new IllegalArgumentException("订单不存在"));
        OrderVersion latestVersion = (OrderVersion)this.versionRepository.findTopByOrderOrderByVersionDesc(existingOrder).orElseThrow(() -> new IllegalStateException("订单版本记录缺失"));
        int update = existingOrder.updateFrom(updatedOrder);
        if (update != 0) {
            return null;
        } else {
            String newHash = this.hashUtils.calculateChainHash(latestVersion.getCurrentHash(), existingOrder.getCoreFields());
            long newVersion = existingOrder.getCurrentVersion() + 1L;
            OrderVersion lastGlobal = this.versionRepository.findLast();
            OrderVersion newVersionRecord = new OrderVersion();
            newVersionRecord.setOrder(existingOrder);
            newVersionRecord.setVersion(newVersion);
            newVersionRecord.setDataSnapshot(this.getCoreFieldsJson(existingOrder));
            newVersionRecord.setPreviousHash(latestVersion.getCurrentHash());
            newVersionRecord.setCurrentHash(newHash);
            newVersionRecord.setUpdateTimestamp(LocalDateTime.now());
            newVersionRecord.setGlobalPreviousHash(lastGlobal.getGlobalCurrentHash());
            newVersionRecord.setGlobalPreviousVersion(lastGlobal);
            String newGlobalHash = this.hashUtils.calculateChainHash(lastGlobal.getGlobalCurrentHash(), existingOrder.getCoreFields());
            newVersionRecord.setGlobalCurrentHash(newGlobalHash);
            this.versionRepository.save(newVersionRecord);
            existingOrder.setPreviousHash(existingOrder.getCurrentHash());
            existingOrder.setCurrentHash(newHash);
            existingOrder.setCurrentVersion(newVersion);
            existingOrder.setUpdateTimestamp(LocalDateTime.now());
            this.orderRepository.save(existingOrder);
            return existingOrder;
        }
    }

    @Transactional(
            readOnly = true
    )
    public boolean verifyOrderIntegrity(Long orderId) {
        Order order = (Order)this.orderRepository.findById(orderId).orElseThrow(() -> new IllegalArgumentException("订单不存在"));
        List<OrderVersion> versions = this.versionRepository.findByOrderOrderByVersionAsc(order);
        if (versions.isEmpty()) {
            // 修改: 使用 logger 替代 System.out.println
            logger.warn("订单无版本记录");
            return false;
        } else {
            OrderVersion firstVersion = (OrderVersion)versions.get(0);
            String expectedFirstHash = this.hashUtils.calculateInitialHash(this.hashUtils.parseCoreFields(firstVersion.getDataSnapshot()));
            if (firstVersion.getCurrentHash().equals(expectedFirstHash) && firstVersion.getPreviousHash() == null) {
                for(int i = 1; i < versions.size(); ++i) {
                    OrderVersion current = (OrderVersion)versions.get(i);
                    OrderVersion previous = (OrderVersion)versions.get(i - 1);
                    if (!current.getPreviousHash().equals(previous.getCurrentHash())) {
                        // 修改: 使用 logger 替代 System.out.println
                        logger.warn("订单版本{" + current.getVersion() + "}被篡改,与上一版本不连续");
                        return false;
                    }

                    String expectedCurrentHash = this.hashUtils.calculateChainHash(previous.getCurrentHash(), this.hashUtils.parseCoreFields(current.getDataSnapshot()));
                    if (!current.getCurrentHash().equals(expectedCurrentHash)) {
                        // 修改: 使用 logger 替代 System.out.println
                        logger.warn("订单版本被篡改" + current.getVersion() + "当前版本hash被篡改");
                        return false;
                    }
                }

                // 修改: 使用 logger 替代 System.out.println
                logger.info("订单哈希链完整，未被篡改");
                return true;
            } else {
                // 修改: 使用 logger 替代 System.out.println
                logger.warn("订单初始版本被篡改");
                return false;
            }
        }
    }

    private String getCoreFieldsJson(Order order) {
        SortedMap<String, Object> fields = order.getCoreFields();
        return this.hashUtils.convertMapToString(fields);
    }

    public Optional<Order> getOrderById(Long id) {
        return this.orderRepository.findById(id);
    }

    public List<OrderVersion> getOrderVersions(Long id) {
        return this.versionRepository.findByOrderOrderByVersionAsc((Order)this.orderRepository.findById(id).get());
    }

    public Optional<OrderVersion> getLatestOrderVersion(Long id) {
        return this.versionRepository.findTopByOrderOrderByVersionDesc((Order)this.orderRepository.findById(id).get());
    }

    public Order createTestOrder() {
        Order order = new Order();
        // 修改: 添加对 idService 为 null 的处理
        if (this.idService != null) {
            order.setId(this.idService.generateId());
        } else {
            // 当 IdService 不可用时使用随机ID
            order.setId(System.currentTimeMillis());
        }
        order.setOrderNo("TEST-" + System.currentTimeMillis());
        Random random = new Random();
        order.setUserId((long)random.nextInt(1000));
        order.setUserName("Test User " + random.nextInt(1000));
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdateTimestamp(LocalDateTime.now());
        order.setCurrentVersion(1L);
        BigDecimal ProductPrice = BigDecimal.valueOf((double)(random.nextFloat() * 100.0F));
        int Quantity = random.nextInt(10) + 1;
        order.setPaymentMethod("Credit Card");
        order.setPaymentStatus(1);
        order.setCurrency("USD");
        order.setAmount(ProductPrice.multiply(BigDecimal.valueOf((long)Quantity)));
        return this.createOrder(order);
    }

    @Generated
    public OrderService(final OrderRepository orderRepository, final OrderVersionRepository versionRepository, final HashUtils hashUtils) {
        this.orderRepository = orderRepository;
        this.versionRepository = versionRepository;
        this.hashUtils = hashUtils;
    }
}